package org.massi.imslp.query;

public class WorkInfo implements IWorkInfo
{

	/**
	 * date of composition
	 */
	private final String dateOfComposition;
	/**
	 * key of the piece (E major etc etc)
	 */
	private final String key;
	/**
	 * instruments
	 */
	private final String score;
	/**
	 * opus number (Op.127)
	 */
	private final String opusNumber;
	/**
	 * piece style (classical, baroque...)
	 */
	private final String style;
	/**
	 * when the piece has been published
	 */
	private final String dateOfPublication;
	/**
	 * dedication
	 */
	private final String dedication;
	/**
	 * comments
	 */
	private final String comments;
	/**
	 * work title
	 */
	private final String title;


	/**
	 * Private constructor using by the {@link Builder}: all fields are present and can be null
	 * 
	 * @param dateOfComposition
	 * @param key
	 * @param score
	 * @param opusNumber
	 * @param style
	 * @param dateOfPublication
	 * @param dedication
	 * @param comments
	 * @param title
	 */
	private WorkInfo(final String dateOfComposition, final String key, final String score,
			final String opusNumber, final String style, final String dateOfPublication, final String dedication,
			final String comments, final String title)
	{
		super();
		this.dateOfComposition = dateOfComposition;
		this.key = key;
		this.score = score;
		this.opusNumber = opusNumber;
		this.style = style;
		this.dateOfPublication = dateOfPublication;
		this.dedication = dedication;
		this.comments = comments;
		this.title = title;
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see org.massi.imslp.query.IWorkInfo#getOpusNumber()
	 */
	@Override
	public String getOpusNumber()
	{
		return this.opusNumber;
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see org.massi.imslp.query.IWorkInfo#getDateOfComposition()
	 */
	@Override
	public String getDateOfComposition()
	{
		return this.dateOfComposition;
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see org.massi.imslp.query.IWorkInfo#getKey()
	 */
	@Override
	public String getKey()
	{
		return this.key;
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see org.massi.imslp.query.IWorkInfo#getScore()
	 */
	@Override
	public String getScore()
	{
		return this.score;
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see org.massi.imslp.query.IWorkInfo#getStyle()
	 */
	@Override
	public String getStyle()
	{
		return this.style;
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see org.massi.imslp.query.IWorkInfo#getDateOfPublication()
	 */
	@Override
	public String getDateOfPublication()
	{
		return this.dateOfPublication;
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see org.massi.imslp.query.IWorkInfo#getDedication()
	 */
	@Override
	public String getDedication()
	{
		return this.dedication;
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see org.massi.imslp.query.IWorkInfo#getComments()
	 */
	@Override
	public String getComments()
	{
		return this.comments;
	}


	@Override
	public String getTitle()
	{
		return this.title;
	}


	@Override
	public String toString()
	{
		return "WorkInfo [dateOfComposition=" + this.dateOfComposition + ", key=" + this.key + ", score=" + this.score
				+ ", opusNumber=" + this.opusNumber + ", style=" + this.style + ", dateOfPublication="
				+ this.dateOfPublication
				+ ", dedication=" + this.dedication + ", comments=" + this.comments + ", title=" + this.title + "]";
	}



	/**
	 * Uses the builder pattern to create instances of {@link WorkInfo} You can create a
	 * {@link WorkInfo} instance like this: <code>
	 * new WorkInfo.Builder().score("2 Violins, cello, viola").dateOfComposition("1814").key("E flat major").build();
	 * </code>
	 */
	public static class Builder
	{
		/**
		 * mimics the structure of WorkInfo
		 */
		private String dateOfComposition, key, score, opusNumber, style, dateOfPublication, dedication, comments,
				title;


		/**
		 * Create a new instance using the internal fields
		 * 
		 * @return a new instance of {@link IWorkInfo}
		 */
		public IWorkInfo build()
		{
			return new WorkInfo(this.dateOfComposition, this.key, this.score, this.opusNumber, this.style,
					this.dateOfPublication, this.dedication, this.comments, this.title);
		}


		/**
		 * Set the score and return the builder instance
		 * 
		 * @param score the instruments used in the piece (violins, cello...)
		 * @return the builder instance
		 */
		public Builder score(final String score)
		{
			this.score = score;
			return this;
		}


		/**
		 * Set the date of composition and return the builder instance
		 * 
		 * @param dateOfComposition when the piece has been composed
		 * @return the builder instance
		 */
		public Builder dateOfComposition(final String dateOfComposition)
		{
			this.dateOfComposition = dateOfComposition;
			return this;
		}


		/**
		 * Set the key and return the builder instance
		 * 
		 * @param key piece key (E flat major...)
		 * @return the builder instance
		 */
		public Builder key(final String key)
		{
			this.key = key;
			return this;
		}


		/**
		 * Set the opus number and return the builder instance
		 * 
		 * @param opus opus number (Op.127)
		 * @return the builder instance
		 */
		public Builder opusNumber(final String opus)
		{
			this.opusNumber = opus;
			return this;
		}


		/**
		 * Set the style and return the builder instance
		 * 
		 * @param style piece style 9classical, baroque, romantic...)
		 * @return the builder instance
		 */
		public Builder style(final String style)
		{
			this.style = style;
			return this;
		}


		/**
		 * Set the date of publication and return the builder instance
		 * 
		 * @param dateOfPublication when the piece has been published
		 * @return the builder instance
		 */
		public Builder dateOfPublication(final String dateOfPublication)
		{
			this.dateOfPublication = dateOfPublication;
			return this;
		}


		/**
		 * Set the dedication and return the builder instance
		 * 
		 * @param dedication piece dedication
		 * @return the builder instance
		 */
		public Builder dedication(final String dedication)
		{
			this.dedication = dedication;
			return this;
		}


		/**
		 * Set the comments and return the builder instance
		 * 
		 * @param comments any generic comments
		 * @return the builder instance
		 */
		public Builder comments(final String comments)
		{
			this.comments = comments;
			return this;
		}


		/**
		 * Set the work title and return the builder instance
		 * 
		 * @param title work title (String quartet...)
		 * @return the builder instance
		 */
		public Builder title(final String title)
		{
			this.title = title;
			return this;
		}


		/*
		 * (non-Javadoc)
		 * 
		 * @see java.lang.Object#toString()
		 */
		@Override
		public String toString()
		{
			return "Builder [dateOfComposition=" + this.dateOfComposition + ", key=" + this.key + ", score="
					+ this.score
					+ ", opusNumber=" + this.opusNumber + ", style=" + this.style + ", dateOfPublication="
					+ this.dateOfPublication
					+ ", dedication=" + this.dedication + ", comments=" + this.comments + ", title=" + this.title + "]";
		}

	}
}
